<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>이벤트 트리거 하기 | Vue 테스팅 핸드북</title>
    <meta name="description" content="">
    <link rel="icon" href="https://lmiller1990.github.io/vue-testing-handbook/img/favicon.png">
  <meta property="og:title" content="Vue Testing Handbook">
  <meta property="og:description" content="Vue testing handbook">
  <meta property="og:type" content="website">
  <meta property="og:url" content="https://lmiller1990.github.io/vue-testing-handbook/">
  <meta property="og:image" content="https://lmiller1990.github.io/vue-testing-handbook/img/og.png">
    
    <link rel="preload" href="/vue-testing-handbook/assets/css/0.styles.99f2ca3b.css" as="style"><link rel="preload" href="/vue-testing-handbook/assets/js/app.14051834.js" as="script"><link rel="preload" href="/vue-testing-handbook/assets/js/3.119a321e.js" as="script"><link rel="preload" href="/vue-testing-handbook/assets/js/2.94957ecd.js" as="script"><link rel="preload" href="/vue-testing-handbook/assets/js/41.db485265.js" as="script"><link rel="prefetch" href="/vue-testing-handbook/assets/js/10.7b1750c8.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/100.87c02eb0.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/101.9f86f8af.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/102.7cf5b3b5.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/103.9a447cc0.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/104.d960f455.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/105.42aa8c19.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/106.fa067e24.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/107.f6145328.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/108.4251a9d9.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/109.6e04b4aa.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/11.c9a15d65.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/110.203be49f.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/111.e66d4c1a.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/112.d5cf2637.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/113.0e1df8ea.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/114.b1d0a5f5.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/115.d21ab6a2.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/116.e13d34ff.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/117.532bedf9.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/118.b99c8d4d.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/119.97666be8.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/12.8ec4d737.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/120.e5fbc47b.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/121.2d6cedde.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/122.7dc3c3fc.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/123.82fcb804.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/124.affd46d3.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/125.10d1ddcb.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/126.8ca1978a.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/127.7b76e158.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/128.e0d8fdce.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/129.e861e49f.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/13.96ee585a.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/130.474092c4.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/131.71e4509c.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/132.b48fe96d.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/133.9268758a.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/134.6a042ef6.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/135.6df261f9.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/136.8aab4165.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/137.60d15690.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/138.29f827fd.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/139.e8db710e.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/14.522b77b9.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/140.8a3b2b26.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/141.cd5f96df.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/142.04a47072.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/143.ac0cb5e1.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/144.c69a73ac.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/15.2f00de2d.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/16.d120a376.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/17.9260e267.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/18.4e3a9d5e.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/19.bfe7cfa3.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/20.52828530.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/21.4d92035b.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/22.49a88bda.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/23.79de1f16.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/24.f45f108e.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/25.48371e8a.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/26.bc7a5470.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/27.49bfeced.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/28.b697055e.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/29.0ef469da.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/30.bd209efe.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/31.ddf8aa10.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/32.95ec3267.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/33.52cf0ebc.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/34.73b1ca03.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/35.be79f171.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/36.52a4dcd2.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/37.a02e83c0.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/38.2a809ae1.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/39.31de0194.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/4.a86536d1.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/40.4a3cfcb7.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/42.8c4375ac.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/43.2f241bb5.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/44.43539973.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/45.619b76a6.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/46.00e17cc1.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/47.faf51fac.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/48.840de9e5.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/49.3410da74.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/5.d3ebdf21.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/50.647913c0.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/51.4990b428.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/52.85ff4209.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/53.7bbf915a.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/54.1fc8316d.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/55.374436d3.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/56.40ebbbe6.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/57.40d9cc46.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/58.37ab0bcf.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/59.8df2efac.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/6.637082cf.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/60.326b4bdd.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/61.449fcfe0.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/62.f05ac3d6.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/63.e1723f7e.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/64.5b9e17ef.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/65.52e8ce24.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/66.cbdf653b.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/67.522e5bfd.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/68.1c27735b.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/69.1f5624e9.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/7.43089f9d.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/70.49fd6b50.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/71.20acc429.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/72.715f4620.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/73.ac123d7d.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/74.59a869d0.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/75.772485ad.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/76.b887e73a.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/77.70e54ee3.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/78.2306c3e7.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/79.e01a6cd1.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/8.4c4cdaa7.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/80.c12fc82f.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/81.44ef90b7.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/82.ff3143a2.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/83.22084435.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/84.485c66f4.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/85.d8afef97.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/86.2ba55e96.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/87.d5642266.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/88.3ad1f8ac.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/89.e370d2fc.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/9.a0f31be6.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/90.2c039dfb.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/91.2c1dd586.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/92.571cd8ae.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/93.b88ae6f6.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/94.16000348.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/95.79a96428.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/96.c86f8cad.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/97.bc1d6c91.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/98.34c6a547.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/99.e1174558.js">
    <link rel="stylesheet" href="/vue-testing-handbook/assets/css/0.styles.99f2ca3b.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/vue-testing-handbook/ko/" class="home-link router-link-active"><!----> <span class="site-name">Vue 테스팅 핸드북</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="Select language" class="dropdown-title"><span class="title">다른 언어로 보기</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/simulating-user-input.html" class="nav-link">English</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/v3/simulating-user-input.html" class="nav-link">v3</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/ja/simulating-user-input.html" class="nav-link">日本語</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/ru/simulating-user-input.html" class="nav-link">Русский (Vue.js 2)</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/v3/ru/simulating-user-input.html" class="nav-link">Русский (Vue.js 3)</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/zh-CN/simulating-user-input.html" class="nav-link">简体中文</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/ko/simulating-user-input.html" class="nav-link router-link-exact-active router-link-active">한국어</a></li></ul></div></div> <a href="https://github.com/lmiller1990/vue-testing-handbook" target="_blank" rel="noopener noreferrer" class="repo-link">
    GitHub
    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><a href="https://vuejs-course.com/" target="_blank"><img id="ad" src="https://raw.githubusercontent.com/lmiller1990/vue-testing-handbook/master/src/.vuepress/public/composition.png" alt="vuejs-course banner"></a> <br> <div class="info"><small>
    Hi! Get $10 off my
    <a href="https://vuejs-course.com/" target="_blank">new</a> <a href="https://vuejs-course.com/" target="_blank">course</a> <a href="https://vuejs-course.com/" target="_blank">on</a> <a href="https://vuejs-course.com/" target="_blank">Vue.js 3</a>,
    <a href="https://vuejs-course.com/" target="_blank">TypeScript and</a>,
    <a href="https://vuejs-course.com/" target="_blank">testing</a>,
    with the discount code VUEJS_COURSE_10_OFF.
    </small></div> <nav class="nav-links"><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="Select language" class="dropdown-title"><span class="title">다른 언어로 보기</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/simulating-user-input.html" class="nav-link">English</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/v3/simulating-user-input.html" class="nav-link">v3</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/ja/simulating-user-input.html" class="nav-link">日本語</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/ru/simulating-user-input.html" class="nav-link">Русский (Vue.js 2)</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/v3/ru/simulating-user-input.html" class="nav-link">Русский (Vue.js 3)</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/zh-CN/simulating-user-input.html" class="nav-link">简体中文</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/ko/simulating-user-input.html" class="nav-link router-link-exact-active router-link-active">한국어</a></li></ul></div></div> <a href="https://github.com/lmiller1990/vue-testing-handbook" target="_blank" rel="noopener noreferrer" class="repo-link">
    GitHub
    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav>  <ul class="sidebar-links"><li><a href="/vue-testing-handbook/ko/" class="sidebar-link">환영합니다</a></li><li><a href="/vue-testing-handbook/ko/setting-up-for-tdd.html" class="sidebar-link">TDD를 위한 설정하기</a></li><li><a href="/vue-testing-handbook/ko/rendering-a-component.html" class="sidebar-link">컴포넌트 렌더하기</a></li><li><a href="/vue-testing-handbook/ko/components-with-props.html" class="sidebar-link">props 테스트하기</a></li><li><a href="/vue-testing-handbook/ko/computed-properties.html" class="sidebar-link">computed 프로퍼티</a></li><li><a href="/vue-testing-handbook/ko/simulating-user-input.html" class="active sidebar-link">사용자 입력 시연하기</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/vue-testing-handbook/ko/simulating-user-input.html#이벤트-트리거-하기" class="sidebar-link">이벤트 트리거 하기</a></li><li class="sidebar-sub-header"><a href="/vue-testing-handbook/ko/simulating-user-input.html#컴포넌트-생성하기" class="sidebar-link">컴포넌트 생성하기</a></li><li class="sidebar-sub-header"><a href="/vue-testing-handbook/ko/simulating-user-input.html#테스트-작성하기" class="sidebar-link">테스트 작성하기</a></li><li class="sidebar-sub-header"><a href="/vue-testing-handbook/ko/simulating-user-input.html#실제-사례" class="sidebar-link">실제 사례</a></li><li class="sidebar-sub-header"><a href="/vue-testing-handbook/ko/simulating-user-input.html#ajax-호출-모킹하기" class="sidebar-link">ajax 호출 모킹하기</a></li><li class="sidebar-sub-header"><a href="/vue-testing-handbook/ko/simulating-user-input.html#결론" class="sidebar-link">결론</a></li></ul></li><li><a href="/vue-testing-handbook/ko/testing-emitted-events.html" class="sidebar-link">emitted 이벤트 테스트하기</a></li><li><a href="/vue-testing-handbook/ko/mocking-global-objects.html" class="sidebar-link">전역 객체 모킹하기</a></li><li><a href="/vue-testing-handbook/ko/stubbing-components.html" class="sidebar-link">컴포넌트 스터빙</a></li><li><a href="/vue-testing-handbook/ko/finding-elements-and-components.html" class="sidebar-link">엘리먼트와 컴포넌트 찾기</a></li><li><a href="/vue-testing-handbook/ko/testing-vuex.html" class="sidebar-link">Vuex 테스트하기</a></li><li><a href="/vue-testing-handbook/ko/vuex-mutations.html" class="sidebar-link">Vuex - 뮤테이션</a></li><li><a href="/vue-testing-handbook/ko/vuex-actions.html" class="sidebar-link">Vuex - 액션</a></li><li><a href="/vue-testing-handbook/ko/vuex-getters.html" class="sidebar-link">Vuex - 게터</a></li><li><a href="/vue-testing-handbook/ko/vuex-in-components.html" class="sidebar-link">컴포넌트 내에 있는 Vuex - $state와 게터</a></li><li><a href="/vue-testing-handbook/ko/vuex-in-components-mutations-and-actions.html" class="sidebar-link">컴포넌트 내에 있는 Vuex - 뮤테이션과 액션</a></li><li><a href="/vue-testing-handbook/ko/vue-router.html" class="sidebar-link">Vue 라우터</a></li><li><a href="/vue-testing-handbook/ko/composition-api.html" class="sidebar-link">컴포지션 API</a></li><li><a href="/vue-testing-handbook/ko/reducing-boilerplate-in-tests.html" class="sidebar-link">보일러플레이트 줄이기</a></li><li><a href="/vue-testing-handbook/ko/jest-mocking-modules.html" class="sidebar-link">Jest - 모듈 모킹하기</a></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h2 id="이벤트-트리거-하기"><a href="#이벤트-트리거-하기" class="header-anchor">#</a> 이벤트 트리거 하기</h2> <p>Vue 컴포넌트에서 하는 일 중 가장 일반적인 것은 사용자의 입력(input)을 받는 일입니다. <code>vue-test-utils</code>와 Jest는 입력을 테스트하는 일을 쉽게 만들어줍니다. <code>trigger</code>와 컴포넌트가 정확하게 작동하는지 검증하는 Jest mocks를 어떻게 사용하는지 살펴보겠습니다.</p> <p>이 페이지에 설명한 테스트의 소스 코드는 <a href="https://github.com/lmiller1990/vue-testing-handbook/tree/master/demo-app/tests/unit/FormSubmitter.spec.js" target="_blank" rel="noopener noreferrer">여기<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>서 찾을 수 있습니다.</p> <h2 id="컴포넌트-생성하기"><a href="#컴포넌트-생성하기" class="header-anchor">#</a> 컴포넌트 생성하기</h2> <p>간단한 형태의 컴포넌트를 만들어보겠습니다. <code>&lt;FormSubmitter&gt;</code>라는 이름이며, <code>&lt;input&gt;</code>과 <code>&lt;button&gt;</code>을 가지고 있습니다. 버튼을 클릭했을 때, 어떤 일이 발생합니다. 첫 예제는 간단하게 성공 메시지를 드러내겠습니다. 그러고 나서 외부 엔드포인트(endpoint)에서 form을 보내는 좀 더 흥미로운 예제를 살펴보겠습니다.</p> <p><code>&lt;FormSubmitter&gt;</code>를 생성하고 템플릿 부분으로 갑니다.</p> <div class="language-html extra-class"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>form</span> <span class="token attr-name">@submit.prevent</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>handleSubmit<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>username<span class="token punctuation">&quot;</span></span> <span class="token attr-name">data-username</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>submit<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>form</span><span class="token punctuation">&gt;</span></span>

    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> 
      <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>message<span class="token punctuation">&quot;</span></span> 
      <span class="token attr-name">v-if</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>submitted<span class="token punctuation">&quot;</span></span>
    <span class="token punctuation">&gt;</span></span>
      Thank you for your submission, {{ username }}.
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>유저가 form을 제출할 때, 제출해줘서 고맙다는 감사 메시지를 드러냅니다. 여기서 비동기적으로 form을 제출하기를 원합니다. 그래서 디폴트 액션(default action)을 막아주기 위해  <code>@submit.prevent</code>를 사용하고 있습니다. 디폴트 액션은 form이 제출될 때 페이지를 새로고침(refresh) 해줍니다.</p> <p>이제 form 제출 로직을 추가하겠습니다.</p> <div class="language-html extra-class"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
  <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
    name<span class="token punctuation">:</span> <span class="token string">&quot;FormSubmitter&quot;</span><span class="token punctuation">,</span>

    <span class="token function">data</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">return</span> <span class="token punctuation">{</span>
        username<span class="token punctuation">:</span> <span class="token string">''</span><span class="token punctuation">,</span>
        submitted<span class="token punctuation">:</span> <span class="token boolean">false</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>

    methods<span class="token punctuation">:</span> <span class="token punctuation">{</span>
      <span class="token function">handleSubmit</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>submitted <span class="token operator">=</span> <span class="token boolean">true</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>꽤 간단합니다. 단지 form이 제출됐을 때, <code>submitted</code>를 <code>true</code>로 설정합니다. 그러고 나면 성공 메시지를 담고 있는 <code>&lt;div&gt;</code> 태그가 드러납니다.</p> <h2 id="테스트-작성하기"><a href="#테스트-작성하기" class="header-anchor">#</a> 테스트 작성하기</h2> <p>작성한 테스트를 보겠습니다. <code>async</code>를 이 테스트에 표시했습니다. 코드를 읽어보고 이유를 찾아보세요.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> shallowMount <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;@vue/test-utils&quot;</span>
<span class="token keyword">import</span> FormSubmitter <span class="token keyword">from</span> <span class="token string">&quot;@/components/FormSubmitter.vue&quot;</span>

<span class="token function">describe</span><span class="token punctuation">(</span><span class="token string">&quot;FormSubmitter&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token function">it</span><span class="token punctuation">(</span><span class="token string">&quot;제출했을 때 알림이 나타난다&quot;</span><span class="token punctuation">,</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> wrapper <span class="token operator">=</span> <span class="token function">shallowMount</span><span class="token punctuation">(</span>FormSubmitter<span class="token punctuation">)</span>

    wrapper<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token string">&quot;[data-username]&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setValue</span><span class="token punctuation">(</span><span class="token string">&quot;alice&quot;</span><span class="token punctuation">)</span>
    wrapper<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token string">&quot;form&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">trigger</span><span class="token punctuation">(</span><span class="token string">&quot;submit.prevent&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">await</span> wrapper<span class="token punctuation">.</span>vm<span class="token punctuation">.</span><span class="token function">$nextTick</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

    <span class="token function">expect</span><span class="token punctuation">(</span>wrapper<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token string">&quot;.message&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">text</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
      <span class="token punctuation">.</span><span class="token function">toBe</span><span class="token punctuation">(</span><span class="token string">&quot;Thank you for your submission, alice.&quot;</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>테스트는 설명할 필요도 없이 꽤 명백합니다. 컴포넌트를  <code>shallowMount</code> 하고, username을 설정합니다. 그리고 사용자의 입력을 시연하기 위해 제공하는 <code>vue-test-utils</code>의 <code>trigger</code> 메서드를 사용합니다. <code>trigger</code>는 커스텀 이벤트로 작동합니다. 수식어(modifier)를 사용하는 이벤트인 <code>submit.prevent</code>, <code>keydown.enter</code> 같은 것들도 마찬가지입니다.</p> <p><code>trigger</code>를 호출한 후에 주목하세요, <code>await wrapper.vm.$nextTick()</code>을 호출합니다. <code>async</code>로 테스트를 표시해야만 하는 이유입니다. 그래야 <code>await</code>을 사용할 수 있습니다. <code>vue-test-utils</code>의 beta 28 버전 시점에서, Vue의 반응성 시스템이 DOM을 업데이트한 것을 확인하기 위해서  <code>nextTick</code>을 호출하는 것이 필요합니다. 때때로 <code>nextTick</code>을 호출하지 않고 진행할 수도 있습니다. 그러나 만약 컴포넌트가 복잡해지기 시작한다면, 레이스 컨디션(race condition)을 맞이할 수도 있고, 어설션(assertion)이 Vue가 DOM을 업데이트하기 전에 동작할 수도 있습니다. 이 부분에 대해서 더 알고 싶다면 <a href="https://vue-test-utils.vuejs.org/guides/#updates-applied-by-vue" target="_blank" rel="noopener noreferrer">vue-test-utils documentation<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>을 읽어보세요.</p> <p>위 테스트는 유닛 테스트의 세 단계를 따릅니다.</p> <ol><li>준비 (테스트를 위한 설정을 합니다. 위의 경우에 컴포넌트를 렌더합니다)</li> <li>행동 (시스템에 있는 행동을 실행합니다)</li> <li>검증 (실제 결과가 기대했던 것과 일치하는지 확인합니다)</li></ol> <p>새로운 라인으로 각각의 단계를 구분해서 테스트를 좀 더 읽기 수월하게 만듭니다.</p> <p><code>yarn test:unit</code>으로 테스트를 실행합니다. 테스트는 통과합니다.</p> <p>트리거는 매우 간단합니다. 몇 가지 입력을 시연하기 원하는 엘리먼트를 갖기 위해 <code>find</code>를 사용합니다. 그리고 이벤트의 이름과 임의의 수식어를 가지고 <code>trigger</code>를 호출합니다.</p> <h2 id="실제-사례"><a href="#실제-사례" class="header-anchor">#</a> 실제 사례</h2> <p>Form은 보통 일부 엔드포인트에서 제출됩니다. <code>handleSubmit</code>의 다른 구현체를 가지고 어떻게 이 컴포넌트를 테스트 할 수 있을지 알아보겠습니다. 한 가지 일반적인 경우는 <code>Vue.prototype.$http</code>의 HTTP 라이브러리에 가명을 사용하는 것입니다. 이렇게 하면 간단하게 <code>this.$http.get(...)</code>을 호출해서 ajax 요청(request)를 할 수 있게 해줍니다.</p> <p>보통 http 라이브러리는 인기있는 HTTP 클라이언트인 <code>axios</code> 입니다. 이 경우에 <code>handleSubmit</code>은 아래와 같이 보일 것입니다.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">handleSubmitAsync</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$http<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">&quot;/api/v1/register&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> username<span class="token punctuation">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>username <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token comment">// 성공 메세지나 기타 등등을 보여줍니다</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token comment">// 에러를 다룹니다</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><p>이 경우에, 한 가지 테크닉은 원하는 테스트 환경을 조성하기 위해서 <code>this.$http</code>를 <em>mock</em> 하는 것입니다. <code>mocks</code> 마운팅 옵션에 대해서는 <a href="https://vue-test-utils.vuejs.org/api/options.html#mocks" target="_blank" rel="noopener noreferrer">여기<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>서 읽어볼 수 있습니다. <code>http.get</code> 메서드의 mock 구현체를 살펴보겠습니다.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> url <span class="token operator">=</span> <span class="token string">''</span>
<span class="token keyword">let</span> data <span class="token operator">=</span> <span class="token string">''</span>

<span class="token keyword">const</span> mockHttp <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token function-variable function">get</span><span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token parameter">_url<span class="token punctuation">,</span> _data</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      url <span class="token operator">=</span> _url
      data <span class="token operator">=</span> _data
      <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>여기서 몇 가지 흥미로운 요소가 있습니다.</p> <ul><li><code>$http.get</code>에 넘겨진 <code>url</code>과 <code>data</code>를 저장하기 위한 <code>url</code>과 <code>data</code> 변수를 생성합니다. 이 작업은 요청이 올바른 엔드포인트와 페이로드(payload)에 맞았는지 검증하는 데 유용합니다.</li> <li><code>url</code>과 <code>data</code> 인자를 할당한 후에, 성공적인 API 응답(response)을 시연하기 위해서 즉시 프로미스(promise)를 resolve 합니다.</li></ul> <p>테스트를 보기 전에, 새로운 <code>handleSubmitAsync</code> 함수를 보겠습니다.</p> <div class="language-js extra-class"><pre class="language-js"><code>methods<span class="token punctuation">:</span> <span class="token punctuation">{</span>
  <span class="token function">handleSubmitAsync</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$http<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">&quot;/api/v1/register&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> username<span class="token punctuation">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>username <span class="token punctuation">}</span><span class="token punctuation">)</span>
      <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>submitted <span class="token operator">=</span> <span class="token boolean">true</span>
      <span class="token punctuation">}</span><span class="token punctuation">)</span>
      <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        <span class="token keyword">throw</span> <span class="token function">Error</span><span class="token punctuation">(</span><span class="token string">&quot;Something went wrong&quot;</span><span class="token punctuation">,</span> e<span class="token punctuation">)</span>
      <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>새로운 <code>handleSubmitAsync</code> 메서드를 사용하기 위해서 <code>&lt;template&gt;</code>도 업데이트 합니다.</p> <div class="language-html extra-class"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>form</span> <span class="token attr-name">@submit.prevent</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>handleSubmitAsync<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>username<span class="token punctuation">&quot;</span></span> <span class="token attr-name">data-username</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>submit<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>form</span><span class="token punctuation">&gt;</span></span>

  <span class="token comment">&lt;!-- ... --&gt;</span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>이제 테스트 하는 일만 남았습니다.</p> <h2 id="ajax-호출-모킹하기"><a href="#ajax-호출-모킹하기" class="header-anchor">#</a> ajax 호출 모킹하기</h2> <p>맨 처음, <code>describe</code> 블록 전의 윗 부분에서 <code>this.$http</code>의 mock 구현체를 추가합니다.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> url <span class="token operator">=</span> <span class="token string">''</span>
<span class="token keyword">let</span> data <span class="token operator">=</span> <span class="token string">''</span>

<span class="token keyword">const</span> mockHttp <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token function-variable function">get</span><span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token parameter">_url<span class="token punctuation">,</span> _data</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      url <span class="token operator">=</span> _url
      data <span class="token operator">=</span> _data
      <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>이제 <code>mocks</code> 마운팅 옵션에 <code>$http</code> mock을 넘기는 테스트를 추가합니다.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">it</span><span class="token punctuation">(</span><span class="token string">&quot;제출했을 때 알림이 나타난다&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> wrapper <span class="token operator">=</span> <span class="token function">shallowMount</span><span class="token punctuation">(</span>FormSubmitter<span class="token punctuation">,</span> <span class="token punctuation">{</span>
    mocks<span class="token punctuation">:</span> <span class="token punctuation">{</span>
      $http<span class="token punctuation">:</span> mockHttp
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>

  wrapper<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token string">&quot;[data-username]&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setValue</span><span class="token punctuation">(</span><span class="token string">&quot;alice&quot;</span><span class="token punctuation">)</span>
  wrapper<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token string">&quot;form&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">trigger</span><span class="token punctuation">(</span><span class="token string">&quot;submit.prevent&quot;</span><span class="token punctuation">)</span>

  <span class="token function">expect</span><span class="token punctuation">(</span>wrapper<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token string">&quot;.message&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">text</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token punctuation">.</span><span class="token function">toBe</span><span class="token punctuation">(</span><span class="token string">&quot;Thank you for your submission, alice.&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>이제 실제 http 라이브러리를 <code>Vue.prototype.$http</code>에 부착해서 사용하는 것 대신에, 위의 mock 구현체를 대신 사용하겠습니다. 테스트 환경을 통제하고 일정한 결과를 가질 수 있다는 점에서 이렇게 하는 것이 좋습니다.</p> <p><code>yarn test:unit</code>을 실행하면 실제로 아래와 같이 실패하는 테스트를 산출합니다.</p> <div class="language-sh extra-class"><pre class="language-sh"><code>FAIL  tests/unit/FormSubmitter.spec.js
  ● FormSubmitter › reveals a notification when submitted

    <span class="token punctuation">[</span>vue-test-utils<span class="token punctuation">]</span>: <span class="token function">find</span> did not <span class="token builtin class-name">return</span> .message, cannot call text<span class="token punctuation">(</span><span class="token punctuation">)</span> on empty Wrapper
</code></pre></div><p><code>mockHttp</code>가 반환한 프로미스가 resolve 되기 전에 테스트가 끝나는 일이 일어나고 있습니다. 아래처럼 테스트를 비동기로 만들 수 있습니다.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">it</span><span class="token punctuation">(</span><span class="token string">&quot;제출했을 때 알림이 나타난다&quot;</span><span class="token punctuation">,</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token comment">// ...</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>하지만 테스트는 여전히 프로미스가 resolve 되기 전에 끝날 것입니다. 이것과 관련해서 할 수 있는 한 가지 방법은 <a href="https://www.npmjs.com/package/flush-promises" target="_blank" rel="noopener noreferrer">flush-promise<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>를 사용하는 것입니다. Flush-promise는 간단한 Node.js 모듈인데, 모든 pending 상태의 프로미스를 즉시 resolve 하는 일을 합니다. <code>yarn add flush-promises</code>로 라이브러리를 설치하고, 아래와 같이 테스트를 업데이트합니다.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> flushPromises <span class="token keyword">from</span> <span class="token string">&quot;flush-promises&quot;</span>
<span class="token comment">// ...</span>

<span class="token function">it</span><span class="token punctuation">(</span><span class="token string">&quot;제출했을 때 알림이 나타난다&quot;</span><span class="token punctuation">,</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> wrapper <span class="token operator">=</span> <span class="token function">shallowMount</span><span class="token punctuation">(</span>FormSubmitter<span class="token punctuation">,</span> <span class="token punctuation">{</span>
    mocks<span class="token punctuation">:</span> <span class="token punctuation">{</span>
      $http<span class="token punctuation">:</span> mockHttp
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>

  wrapper<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token string">&quot;[data-username]&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setValue</span><span class="token punctuation">(</span><span class="token string">&quot;alice&quot;</span><span class="token punctuation">)</span>
  wrapper<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token string">&quot;form&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">trigger</span><span class="token punctuation">(</span><span class="token string">&quot;submit.prevent&quot;</span><span class="token punctuation">)</span>

  <span class="token keyword">await</span> <span class="token function">flushPromises</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

  <span class="token function">expect</span><span class="token punctuation">(</span>wrapper<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token string">&quot;.message&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">text</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token punctuation">.</span><span class="token function">toBe</span><span class="token punctuation">(</span><span class="token string">&quot;Thank you for your submission, alice.&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p><code>flush-promises</code>를 사용하면 모든 프로미스를 확인하는 꽤 괜찮은 부수 효과를 가집니다. 이 부수효과에는 <code>nextTick</code>을 resolve 한 것과 Vue가 DOM을 업데이트한 것을 포함됩니다.</p> <p>이제 테스트는 통과합니다. <code>flush-promises</code>의 소스코드는 10줄밖에 안 됩니다. Node.js에 관심이 있다면, 읽어보고 어떻게 작동하는지 이해하는 것도 값진 일일 것입니다.</p> <p>엔드포인트와 페이로드가 정확한지도 확인해야 합니다. 테스트에 두 개의 어설션을 추가합니다.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// ...</span>
<span class="token function">expect</span><span class="token punctuation">(</span>url<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toBe</span><span class="token punctuation">(</span><span class="token string">&quot;/api/v1/register&quot;</span><span class="token punctuation">)</span>
<span class="token function">expect</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toEqual</span><span class="token punctuation">(</span><span class="token punctuation">{</span> username<span class="token punctuation">:</span> <span class="token string">&quot;alice&quot;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>테스트는 여전히 통과합니다.</p> <h2 id="결론"><a href="#결론" class="header-anchor">#</a> 결론</h2> <p>이 섹션에서는 아래와 같은 방법을 알게 됐습니다.</p> <ul><li><code>prevent</code>같은 수식어를 사용하는 이벤트도 포함한 이벤트에 <code>trigger</code>를 사용하는 방법</li> <li><code>v-model</code>을 사용하는 <code>&lt;input&gt;</code>의 값을 설정하기 위해 <code>setValue</code> 사용하는 방법</li> <li>유닛 테스트의 세 단계를 사용해서 테스트를 작성하는 방법</li> <li><code>mocks</code>를 마운트하는 옵션을 사용해서, <code>Vue.prototype</code>에 부착된 메서드를 mock 하는 방법</li> <li>모든 프로미스를 즉시 해결하기 위해서, 유닛 테스트에서 유용한 기술인  <code>flush-promises</code>를 사용하는 방법</li></ul> <p>이 페이지에 설명한 테스트의 소스 코드는 <a href="https://github.com/lmiller1990/vue-testing-handbook/tree/master/demo-app/tests/unit/FormSubmitter.spec.js" target="_blank" rel="noopener noreferrer">여기<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>에서 찾을 수 있습니다.</p></div> <footer class="page-edit"><div class="edit-link"><a href="https://github.com/lmiller1990/vue-testing-handbook/edit/master/ko/simulating-user-input.md" target="_blank" rel="noopener noreferrer">Github에서 이 페이지 수정하기</a> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></div> <div class="last-updated"><span class="prefix">마지막 업데이트:</span> <span class="time">2020. 1. 27. 오후 6:02:09</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev">
      ←
      <a href="/vue-testing-handbook/ko/computed-properties.html" class="prev">computed 프로퍼티</a></span> <span class="next"><a href="/vue-testing-handbook/ko/testing-emitted-events.html">emitted 이벤트 테스트하기</a>
      →
    </span></p></div> </main></div><div class="global-ui"></div></div>
    <script src="/vue-testing-handbook/assets/js/app.14051834.js" defer></script><script src="/vue-testing-handbook/assets/js/3.119a321e.js" defer></script><script src="/vue-testing-handbook/assets/js/2.94957ecd.js" defer></script><script src="/vue-testing-handbook/assets/js/41.db485265.js" defer></script>
  </body>
</html>
